package reflect;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @ClassName ReflectTest
 * @Author 刘正星
 * @Date 2021/6/20 下午11:00
 * @Description
 */
public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {

        //获取class对象方式
        // 1.forName获取

        Class pclass = Class.forName("reflect.Person");
        System.out.println(pclass);

        Method toString = pclass.getDeclaredMethod("toString");
        Method setName = pclass.getDeclaredMethod("setName", String.class);
        Method setId = pclass.getDeclaredMethod("setId", int.class);


        System.out.println(toString.getName()+"   toString?");

        Person o = (Person)pclass.newInstance();

        setName.invoke(o,"liuzhengxing");

        setId.invoke(o,1);

        System.out.println(o.toString());

        System.out.println(toString.invoke(o));


        // 2. 通过对象获取
        Person person = new Person();

        Class<? extends Person> aClass = person.getClass();
        System.out.println(aClass);
       // 3. 通过类名.class获取
        Class<Person> personClass = Person.class;
        System.out.println(personClass);

        //4 包装器类可以通过如下方式获取class对象

        Class<Integer> type = Integer.TYPE;
        System.out.println(type);

        // 5 通过classLoader类加载器

        //唯一、同一个class对象。hashcode一致
        System.out.println(pclass.hashCode()+" = "+aClass.hashCode()+" = "+personClass.hashCode());

        System.out.println(pclass.getName()+" "+pclass.getSimpleName());
        //获取父类类型,顶级父类Object

        Class superclass = pclass.getSuperclass();

        System.out.println(superclass);

        //哪些类型可以用class对象:class interface []数组 enum枚举 annotation注解 primitive type基本数据类型 void

        Class<Object> objectClass = Object.class;

        Class<Comparable> comparableClass = Comparable.class;

        Class<String[]> aClass1 = String[].class;

        Class<int[][]> aClass2 = int[][].class;

        Class<Override> overrideClass = Override.class;

        Class<ElementType> elementTypeClass = ElementType.class;

        Class<Integer> intClass = int.class;

        Class<Void> voidClass = void.class;

        System.out.println("哪些类型可以用class对象=====================================");

        System.out.println(objectClass);
        System.out.println(comparableClass);
        System.out.println(aClass1);
        System.out.println(aClass2);
        System.out.println(overrideClass);
        System.out.println(elementTypeClass);
        System.out.println(intClass);
        System.out.println(voidClass);

        /*
          主要API
         */
        System.out.println("主要API=========================");
        //获取类的所有属性 只能获取public修饰的
        Field[] fields = pclass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        //获取所有的属性 不管什么修饰符都可以拿到

        Field[] declaredFields = pclass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        //同理获取方法

        Method[] methods = pclass.getMethods();

        Method[] declaredMethods = pclass.getDeclaredMethods();

        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);

        }

        System.out.println(pclass.getAnnotation(MyAnnotation.class));


    }
}
